import React, { useState, useMemo } from 'react';
import { useDiaryStore } from '../../store/diaryStore';
import { useChartContext } from '../../contexts/ChartContext';

interface WordCloudChartProps {
  maxWords?: number;
  minFrequency?: number;
}

interface WordData {
  text: string;
  frequency: number;
  size: number;
  color: string;
  x: number;
  y: number;
}

const WordCloudChart: React.FC<WordCloudChartProps> = ({ maxWords = 50, minFrequency = 2 }) => {
  const entries = useDiaryStore((state) => state.entries);
  const { filters, setFilters } = useChartContext();
  const [selectedWord, setSelectedWord] = useState<string | null>(null);
  const [hoveredWord, setHoveredWord] = useState<string | null>(null);

  // Color palette for words
  const colorPalette = [
    '#3b82f6', '#ef4444', '#10b981', '#f59e0b', '#8b5cf6',
    '#06b6d4', '#ec4899', '#84cc16', '#f97316', '#6366f1',
    '#14b8a6', '#f43f5e', '#22c55e', '#a855f7', '#0ea5e9'
  ];

  // Common words to filter out
  const stopWords = new Set([
    'the', 'a', 'an', 'and', 'or', 'but', 'in', 'on', 'at', 'to', 'for', 'of', 'with', 'by',
    'i', 'you', 'he', 'she', 'it', 'we', 'they', 'me', 'him', 'her', 'us', 'them',
    'my', 'your', 'his', 'her', 'its', 'our', 'their',
    'this', 'that', 'these', 'those', 'is', 'am', 'are', 'was', 'were', 'be', 'been', 'being',
    'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would', 'could', 'should',
    'can', 'may', 'might', 'must', 'shall',
    'not', 'no', 'yes', 'so', 'very', 'just', 'now', 'then', 'here', 'there', 'where',
    'when', 'why', 'how', 'what', 'who', 'which', 'all', 'any', 'some', 'each', 'every',
    'other', 'another', 'such', 'only', 'own', 'same', 'few', 'more', 'most', 'much',
    'many', 'long', 'well', 'way', 'even', 'back', 'still', 'also', 'after', 'before'
  ]);

  // Extract and process words from entries
  const wordFrequency = useMemo(() => {
    const wordMap = new Map<string, number>();
    
    entries.forEach(entry => {
      // Remove HTML tags and extract text
      const text = entry.content.replace(/<[^>]*>/g, ' ');
      
      // Split into words and clean them
      const words = text
        .toLowerCase()
        .replace(/[^a-zA-Z\s]/g, ' ')
        .split(/\s+/)
        .filter(word => 
          word.length > 2 && 
          !stopWords.has(word) &&
          !/^\d+$/.test(word) // Remove pure numbers
        );
      
      words.forEach(word => {
        wordMap.set(word, (wordMap.get(word) || 0) + 1);
      });
    });
    
    return Array.from(wordMap.entries())
      .filter(([_, frequency]) => frequency >= minFrequency)
      .sort((a, b) => b[1] - a[1])
      .slice(0, maxWords)
      .map(([word, frequency], index) => ({
        text: word,
        frequency,
        size: Math.max(12, Math.min(48, 12 + (frequency * 4))),
        color: colorPalette[index % colorPalette.length]
      }));
  }, [entries, maxWords, minFrequency]);

  // Simple spiral layout algorithm
  const generateLayout = (words: Omit<WordData, 'x' | 'y'>[]): WordData[] => {
    const width = 600;
    const height = 400;
    const centerX = width / 2;
    const centerY = height / 2;
    
    const positioned: WordData[] = [];
    
    words.forEach((word, index) => {
      let placed = false;
      let radius = 0;
      let angle = 0;
      
      // Try to place the word in a spiral pattern
      while (!placed && radius < Math.min(width, height) / 2) {
        const x = centerX + radius * Math.cos(angle);
        const y = centerY + radius * Math.sin(angle);
        
        // Estimate text dimensions
        const textWidth = word.text.length * (word.size * 0.6);
        const textHeight = word.size;
        
        // Check if position is within bounds
        if (x - textWidth/2 > 0 && x + textWidth/2 < width &&
            y - textHeight/2 > 0 && y + textHeight/2 < height) {
          
          // Check for collisions with existing words
          const hasCollision = positioned.some(existing => {
            const existingWidth = existing.text.length * (existing.size * 0.6);
            const existingHeight = existing.size;
            
            return Math.abs(x - existing.x) < (textWidth + existingWidth) / 2 + 10 &&
                   Math.abs(y - existing.y) < (textHeight + existingHeight) / 2 + 5;
          });
          
          if (!hasCollision) {
            positioned.push({ ...word, x, y });
            placed = true;
          }
        }
        
        // Move along spiral
        angle += 0.5;
        if (angle > Math.PI * 2) {
          angle = 0;
          radius += 5;
        }
      }
      
      // If couldn't place in spiral, place randomly
      if (!placed) {
        const x = Math.random() * (width - 100) + 50;
        const y = Math.random() * (height - 50) + 25;
        positioned.push({ ...word, x, y });
      }
    });
    
    return positioned;
  };

  const wordLayout = useMemo(() => generateLayout(wordFrequency), [wordFrequency]);

  const handleWordClick = (word: string) => {
    if (filters.searchQuery === word) {
      // If clicking the same word, clear the filter
      setFilters({ searchQuery: '' });
    } else {
      // Set new search query
      setFilters({ searchQuery: word });
    }
  };

  const clearSelection = () => {
    setSelectedWord(null);
    setFilters({ searchQuery: '' });
  };

  if (wordLayout.length === 0) {
    return (
      <div className="bg-white rounded-lg shadow-sm border border-warm-gray-200 p-6">
        <h3 className="text-lg font-semibold text-warm-gray-800 mb-4">
          Word Cloud
        </h3>
        <div className="flex items-center justify-center h-64 text-warm-gray-500">
          <div className="text-center">
            <p className="text-lg mb-2">No words to display</p>
            <p className="text-sm">Write more entries to see your most used words</p>
          </div>
        </div>
      </div>
    );
  }

  return (
    <div className="bg-white rounded-lg shadow-sm border border-warm-gray-200 p-6">
      <div className="flex items-center justify-between mb-4">
        <h3 className="text-lg font-semibold text-warm-gray-800">
          Word Cloud
        </h3>
        <div className="flex items-center gap-2">
          {selectedWord && (
            <button
              onClick={clearSelection}
              className="text-xs bg-red-100 text-red-700 px-2 py-1 rounded hover:bg-red-200 transition-colors"
            >
              Clear Selection
            </button>
          )}
          <span className="text-xs text-warm-gray-500">
            Showing top {wordLayout.length} words
          </span>
        </div>
      </div>

      {selectedWord && (
        <div className="mb-4 p-3 bg-blue-50 rounded-lg">
          <p className="text-sm text-blue-800">
            Searching for: <span className="font-medium">"{selectedWord}"</span>
            <span className="ml-2 text-blue-600">
              (appears {wordLayout.find(w => w.text === selectedWord)?.frequency} times)
            </span>
          </p>
        </div>
      )}

      <div className="relative overflow-hidden rounded-lg bg-gradient-to-br from-blue-50 to-purple-50" style={{ height: '400px' }}>
        <svg width="100%" height="100%" viewBox="0 0 600 400">
          {wordLayout.map((word, index) => {
            const isSelected = selectedWord === word.text;
            const isHovered = hoveredWord === word.text;
            const opacity = isSelected ? 1 : isHovered ? 0.8 : 0.7;
            const scale = isHovered ? 1.1 : 1;
            
            return (
              <text
                key={`${word.text}-${index}`}
                x={word.x}
                y={word.y}
                fontSize={word.size}
                fill={word.color}
                textAnchor="middle"
                dominantBaseline="middle"
                className="cursor-pointer select-none transition-all duration-200"
                style={{
                  opacity,
                  transform: `scale(${scale})`,
                  transformOrigin: `${word.x}px ${word.y}px`,
                  fontWeight: isSelected ? 'bold' : 'normal',
                  filter: isSelected ? 'drop-shadow(2px 2px 4px rgba(0,0,0,0.3))' : 'none'
                }}
                onClick={() => handleWordClick(word.text)}
                onMouseEnter={() => setHoveredWord(word.text)}
                onMouseLeave={() => setHoveredWord(null)}
              >
                {word.text}
              </text>
            );
          })}
        </svg>
        
        {/* Hover tooltip */}
        {hoveredWord && (
          <div className="absolute bottom-4 left-4 bg-white p-2 rounded-lg shadow-lg border border-warm-gray-200">
            <p className="text-sm font-medium text-warm-gray-800">{hoveredWord}</p>
            <p className="text-xs text-warm-gray-600">
              Used {wordLayout.find(w => w.text === hoveredWord)?.frequency} times
            </p>
            <p className="text-xs text-blue-600 mt-1">
              Click to search entries
            </p>
          </div>
        )}
      </div>

      <div className="mt-4 text-xs text-warm-gray-500">
        <div className="flex items-center justify-between">
          <p>
            <strong>Tip:</strong> Click on any word to search for entries containing it.
          </p>
          <p className="text-right">
            Min frequency: {minFrequency} • Max words: {maxWords}
          </p>
        </div>
        <p className="mt-1">
          Word size represents frequency. Common words (the, and, is, etc.) are filtered out.
        </p>
      </div>
    </div>
  );
};

export default WordCloudChart;